package edu.rmit.client;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.rmi.RemoteException;
import java.util.List;

import javax.swing.BorderFactory;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ListModel;
import javax.swing.ListSelectionModel;

import edu.rmit.contant.RoleType;
import edu.rmit.domain.Group;
import edu.rmit.domain.User;
import edu.rmit.service.IGroupService;
import edu.rmit.util.PromotDialog;

/**
 * The class is to display the current active interest group, and some
 * corresponding control to implement the function.
 * 
 * @author Joey George
 * @version 1.0
 */
@SuppressWarnings("serial")
public class GroupListPanel extends JPanel {
	/**
	 * The window initialize height.
	 */
	private static int HEIGHT = 480;

	/**
	 * The window initialize width.
	 */
	private static int WIDTH = 400;

	/**
	 * The JFrame which display the system window.
	 */
	private JFrame frame;

	/**
	 * The label which display the welcome information.
	 */
	private JLabel labelWelcome;

	/**
	 * The list which list the currently active groups.
	 */
	private JList listGroup;

	/**
	 * The button which clicked will logout the current user.
	 */
	private JButton buttonLogout;

	/**
	 * The button which clicked will delete the current selected group.
	 */
	private JButton buttonDeleteGroup;

	/**
	 * The button which clicked will create a new group.
	 */
	private JButton buttonCreateGroup;

	/**
	 * The button which clicked will suspend a user.
	 */
	private JButton buttonSuspendUsers;

	/**
	 * The button which clicked will review the group request.
	 */
	private JButton buttonReviewGroupRequest;

	/**
	 * The client instance which provide the service.
	 */
	private Client client;

	/**
	 * The list which display the interest groups.
	 */
	private List<Group> interestGroup;

	/**
	 * The currently logined user.
	 */
	private User user;

	/**
	 * The constructor which display the currently active interesting group. And
	 * also initialize some corresponding control.
	 * 
	 * @param client
	 *            The client instance which provide the service.
	 * @param user
	 *            The currently logined user.
	 */
	public GroupListPanel(Client client, User user) {
		this.client = client;
		this.user = user;

		labelWelcome = new JLabel("Welcome:" + user.getUserName());
		Font font = new Font("", Font.BOLD, 20);
		labelWelcome.setFont(font);
		JPanel panelWelcome = new JPanel();
		panelWelcome.add(labelWelcome);
		panelWelcome.setBorder(BorderFactory.createTitledBorder(""));

		String[] groupNames = null;
		try {
			interestGroup = client.getGroupService().getInterestGroups(true);
			groupNames = new String[interestGroup.size()];
			for (int i = 0; i < interestGroup.size(); i++) {
				groupNames[i] = interestGroup.get(i).getName();
			}
		} catch (RemoteException e) {
			e.printStackTrace();
		}

		// Customize the list properties
		listGroup = new JList(groupNames);
		listGroup.setVisibleRowCount(5);
		listGroup.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		listGroup.setFixedCellHeight(25);
		listGroup.setFixedCellWidth(200);

		// Change the colors of the lists
		listGroup.setBackground(Color.gray);
		listGroup.setForeground(Color.white);

		listGroup.addMouseListener(new ListenerChooseGroup());

		// Add lists to the scrollbar containers
		add(new JScrollPane(listGroup, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
				JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS));
		JPanel groupPanel = new JPanel();
		groupPanel.add(new JLabel("All interest groups:"));
		groupPanel.add(listGroup);
		groupPanel.setBorder(BorderFactory.createTitledBorder("Groups"));

		JPanel panelright = new JPanel();
		panelright.setLayout(new GridLayout(9, 1));
		panelright.add(new JLabel(""));
		buttonCreateGroup = new JButton("Create a group");
		buttonCreateGroup.addActionListener(new ListenerCreateGroup());
		buttonLogout = new JButton("Log out");
		buttonLogout.addActionListener(new ListenerLogout());
		buttonSuspendUsers = new JButton("Suspend Users");
		buttonSuspendUsers.addActionListener(new ListenerDenyUser());
		buttonReviewGroupRequest = new JButton("Review Group Request");
		buttonReviewGroupRequest
				.addActionListener(new ListenerReviewGroupRequest());
		buttonDeleteGroup = new JButton("Remove Group");
		buttonDeleteGroup.addActionListener(new ListenerDeleteGroup());

		panelright.add(new JLabel(""));
		panelright.add(buttonCreateGroup);
		if (user.getRoleType() == RoleType.ADMIN) {
			panelright.add(buttonDeleteGroup);
			panelright.add(buttonSuspendUsers);
			panelright.add(buttonReviewGroupRequest);
		} else {
			panelright.add(new JLabel(""));
			panelright.add(new JLabel(""));
			panelright.add(new JLabel(""));
		}

		panelright.add(buttonLogout);
		panelright.add(new JLabel(""));
		panelright.add(new JLabel(""));
		panelright.setBorder(BorderFactory.createTitledBorder("Operations"));

		frame = new JFrame("Group List");
		initFrame();
		frame.add(panelWelcome, BorderLayout.NORTH);
		frame.add(groupPanel, BorderLayout.CENTER);
		frame.add(panelright, BorderLayout.EAST);

	}

	/**
	 * The method is to initialize the frame window
	 */
	private void initFrame() {
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setResizable(false);
		frame.setVisible(true);
		frame.setSize(WIDTH, HEIGHT);

		Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
		Dimension frameSize = frame.getSize();
		if (frameSize.height > screenSize.height) {
			frameSize.height = screenSize.height;
		}
		if (frameSize.width > screenSize.width) {
			frameSize.width = screenSize.width;
		}
		frame.setLocation((screenSize.width - frameSize.width) / 2,
				(screenSize.height - frameSize.height) / 2);
		
		frame.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				try {
					if (user != null) {
						client.getUserService().changeLoginStatus(
								user.getUserName(), false);
					}
					frame.dispose();
				} catch (Exception ex) {
					ex.printStackTrace();
				}
			}
		});
	}

	/**
	 * The Listener class is to deal with the create group request.
	 * 
	 * @author Joey George
	 * @version 1.0
	 */
	class ListenerCreateGroup implements ActionListener {
		/**
		 * This method is to deal with when the create group button clicked.
		 */
		public void actionPerformed(ActionEvent event) {
			new CreateGroupPanel(client, user);
		}
	}

	/**
	 * The Listener class is to deal with the user logout button clicked.
	 * 
	 * @author Joey George
	 * @version 1.0
	 * 
	 */
	class ListenerLogout implements ActionListener {
		public void actionPerformed(ActionEvent event) {
			try {
				client.getUserService().changeLoginStatus(user.getUserName(), false);
			} catch (RemoteException e) {
				e.printStackTrace();
			}
			frame.dispose();
			new LoginPanel(client);
		}
	}

	/**
	 * The Listener class is to deal with the administrator deny user button
	 * clicked.
	 * 
	 * @author Joey George
	 * @version 1.0
	 */
	class ListenerDenyUser implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			new SuspendUserPanel(client);
		}
	}

	/**
	 * The Listener class is to deal with the administrator review group request
	 * button clicked.
	 * 
	 * @author Joey George
	 * @version 1.0
	 */
	class ListenerReviewGroupRequest implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			List<Group> newRequestedGroups = null;
			try {
				newRequestedGroups = client.getGroupService()
						.getInterestGroups(false);
			} catch (RemoteException e1) {
				e1.printStackTrace();
			}
			if (newRequestedGroups.size() > 0) {
				new ReviewGroupRequestPanel(frame, user, client);
			} else {
				String title = "Promote Information";
				String info = "Currently is no new group request!";
				PromotDialog.infoMessageBox(null, title, info);
			}
		}
	}

	/**
	 * The listener class is to deal with the user choose group button clicked.
	 * 
	 * @author Joey George
	 * @version 1.0
	 * 
	 */
	class ListenerChooseGroup extends MouseAdapter {

		/**
		 * This method is to deal the the event when a user double clicked the
		 * interest group's item. This will open a new window the group memeber
		 * can chat.
		 */
		@Override
		public void mouseClicked(MouseEvent e) {
			if (e.getClickCount() == 2) {
				int index = listGroup.locationToIndex(e.getPoint());
				Group group = null;
				try {
					List<Group> groups = client.getGroupService()
							.getInterestGroups(true);
					group = groups.get(index);

					new LiveChatPanel(client, group.getId(), user);
				} catch (RemoteException e1) {
					e1.printStackTrace();
				}
			}
		}
	}

	/**
	 * The listener clas is to deal with when a user clicked the delete group
	 * button, the selected group will be removed from the list.
	 * 
	 * @author Joey George
	 * @version 1.0
	 * 
	 */
	class ListenerDeleteGroup implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			int index = listGroup.getSelectedIndex();
			if (index == -1) {
				String title = "Error Delete Group";
				String reason = "Please select an active group!";
				PromotDialog.errorMessageBox(null, title, reason);
			} else {
				Group group = null;
				try {
					IGroupService groupService = client.getGroupService();
					List<Group> groups = groupService.getInterestGroups(true);
					group = groups.get(index);
					changeMessageList(listGroup, index);
					groupService.removeGroup(group.getId());
				} catch (RemoteException e1) {
					e1.printStackTrace();
				}
			}
		}

		/**
		 * This method is to change the interesting group's list, and remove the
		 * index which the user is currently selected.
		 * 
		 * @param listMessage
		 *            The interesting group list.
		 * @param index
		 *            The selected index of the interesing group.
		 */
		private void changeMessageList(JList listMessage, int index) {
			DefaultListModel listModel = new DefaultListModel();
			ListModel currentListModel = listMessage.getModel();
			for (int i = 0; i < currentListModel.getSize(); i++) {
				if (i != index) {
					listModel
							.addElement(listMessage.getModel().getElementAt(i));
				}
			}
			interestGroup.remove(index);
			listMessage.setModel(listModel);
		}
	}
}
